<?php
declare(strict_types=1);

/**
 * Created by .
 * User: luogan
 * Date: 2021/12/18
 */
use App\Constants\ErrorCode;
use App\Exception\ErrorException;
use App\Exception\TokenException;
use Hyperf\Utils\Context;
use HyperfExt\Jwt\Exceptions\JwtException;
use HyperfExt\Jwt\Contracts\JwtFactoryInterface;
use Psr\Http\Message\ServerRequestInterface;
use Laminas\Stdlib\ResponseInterface;
use Hyperf\Utils\ApplicationContext;
use App\Model\AdminLog;


if (!function_exists('container')) {
    /**
     * 容器实例
     * @return \Psr\Container\ContainerInterface
     */
    function container()
    {
        return ApplicationContext::getContainer();
    }
}

if (!function_exists('request')) {
    /**
     * 请求实例
     * @return mixed|ServerRequestInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    function request()
    {
        return container()->get(ServerRequestInterface::class);
    }
}

if (!function_exists('response')) {
    /**
     * 响应实例
     * @return mixed|ServerRequestInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    function response()
    {
        return container()->get(ResponseInterface::class);
    }
}

if (!function_exists('redis')) {

    /**
     * redis 实例
     * @return mixed|Redis
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    function redis()
    {
        return container()->get(Redis::class);
    }
}

if (!function_exists('jwt')) {

    /**
     * jwt 实例
     * @return \HyperfExt\Jwt\Jwt
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    function jwt()
    {
        return container()->get(JwtFactoryInterface::class)->make();
    }
}

if (!function_exists('api')) {

    /**
     * 通用返回json
     * @param $msg
     * @param $data
     * @param $code
     * @return false|string
     */
    function api($msg, $data, $code)
    {
        $api_data = [
            'message' => $msg,
            'code' => $code,
            'time' => date('Y-m-d H:i:s',time()),
            'data' => $data,
        ];
        return json_encode($api_data, JSON_UNESCAPED_UNICODE);
    }

}

if (!function_exists('error')) {
    /**
     * 通用失败json
     * @param $msg
     * @param int $code
     * @param array $data
     * @return false|string
     */
    function error($msg,$code = ErrorCode::COMMON_ERROR_CODE,$data = [])
    {
        if (!$msg) $msg = ErrorCode::getMessage($code);
        return api($msg, $data, $code);
    }
}

if (!function_exists('success')) {

    /**
     * 通用成功json
     * @param $msg
     * @param array $data
     * @param int $code
     * @return false|string
     */
    function success($msg,$data = [],$code = ErrorCode::SUCCESS_CODE)
    {
        if (!$msg) $msg = ErrorCode::getMessage($code);
        return api($msg, $data, $code);
    }
}

if (!function_exists('dd')) {

    /**
     * 测试打印
     * @param array|string $data
     * @return array|string
     */
    function dd($data)
    {
        var_dump($data);die();
    }
}

if (!function_exists('verify_ip')) {
    function verify_ip($realip)
    {
        return filter_var($realip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4);
    }
}

if (!function_exists('get_client_ip')) {
    /**
     * 获取ip地址
     * @return mixed|string
     */
    function get_client_ip()
    {
        try {
            $request = Context::get(ServerRequestInterface::class);
            $ip_addr = $request->getHeaderLine('x-forwarded-for');
            if (verify_ip($ip_addr)) {
                return $ip_addr;
            }
            $ip_addr = $request->getHeaderLine('remote-host');
            if (verify_ip($ip_addr)) {
                return $ip_addr;
            }
            $ip_addr = $request->getHeaderLine('x-real-ip');
            if (verify_ip($ip_addr)) {
                return $ip_addr;
            }
            $ip_addr = $request->getServerParams()['remote_addr'] ?? '0.0.0.0';
            if (verify_ip($ip_addr)) {
                return $ip_addr;
            }
        } catch (Throwable $e) {
            return '0.0.0.0';
        }
        return '0.0.0.0';
    }
}
if (!function_exists('admin_info')) {
    /**
     * 获取当前管理员信息
     * @return array
     * @throws \HyperfExt\Jwt\Exceptions\JwtException
     */
    function admin_info()
    {
        try {
            $jwt= jwt();
            $token = $jwt->parseToken();
            $payload = $token->getPayload();
        } catch (JwtException $jwtException) {
            throw new TokenException('请重新登录');
        }
        $data = [
            'admin_id' => $payload['admin_id'],
            'user_name' => $payload['username'],
            'role' => $payload['role']
        ];
        return $data;
    }
}
if (!function_exists('admin_id')) {
    /**
     * 获取当前管理员id
     * @return mixed
     * @throws \HyperfExt\Jwt\Exceptions\JwtException
     */
    function admin_id()
    {
        try {
            $jwt= jwt();
            $token = $jwt->parseToken();
            $payload = $token->getPayload();
        } catch (JwtException $jwtException) {
            throw new TokenException('请重新登录');
        }
        return $payload['admin_id'];
    }
}
if (!function_exists('action_url')) {
    /**
     * 获取请求路由
     * @return string
     */
    function action_url()
    {
        $request = Context::get(ServerRequestInterface::class);
        $currUrl = $request->getUri()->getPath();
        return $currUrl;
    }
}

if (!function_exists('admin_log')) {
    /**
     * 管理员操作日志
     * @param $remark
     * @throws ErrorException
     */
    function admin_log($remark)
    {
        $admin = admin_info();
        $data = [
            'admin_id' => $admin['admin_id'],
            'username' =>$admin['user_name'],
            'ip' => get_client_ip(),
            'remark' => $remark,
            'action' =>action_url()
        ];
        $result = AdminLog::create($data);
        if (!$result){
            throw new ErrorException('操作日志生成失败');
        }
    }
}


